<template>
  <div>
    <main>
      <div class="title-container">
        <h1>电影信息表</h1>
        <ul class="title">
          <li>
            <span class="selected-all" @click="selectAll">All</span>
            <span v-for="item of titles" :key="item"> {{ item }}</span>
          </li>
        </ul>
      </div>
      <!-- <div class="table" id="listWrap" ref="listWrap" @scroll="handleScroll"> -->
      <div class="table" id="listWrap" ref="listWrap">
        <div class="scroll-bar" ref="scrollBar"></div>
        <ul id="tbody" class="tbody" ref="list">
          <li
            v-for="(item, index) in showList"
            :key="index"
            :class="{ changeColorNo: item.status }"
          >
            <span @click="getClickNo(index)" class="col-1"
              ><label id="label" :for="'film' + index"
                ><input
                  type="checkbox"
                  v-model="item.status"
                  class="film-option"
                  :id="'film' + index" /></label
            ></span>
            <span @click="getClickNo(index)">{{ index + 1 + start }}</span>
            <span @click="getClickNo(index)">{{ item.name }}</span>
            <span @click="getClickNo(index)">{{ item.desc }}</span>
            <span
              ><el-rate
                v-model="item.score"
                disabled
                show-text
                text-color="#8076a3"
                void-icon-class="icon-rate-face-off"
                :texts="['烂片', '还行', '一般', '佳作', '神作']"
                :colors="['#70887d', '#bec936', '#20894d']"
              >
              </el-rate
            ></span>
            <span
              ><input
                value="修改"
                type="button"
                class="button"
                @click="editFilmInfo(index)" />
              <input
                value="删除"
                @click="onDelete(index)"
                type="button"
                class="button" />
              <el-button
                @click="addFilmInfo(index)"
                type="primary"
                icon="el-icon-circle-plus"
                round
              ></el-button
            ></span>
          </li>
        </ul>
      </div>
      <div class="box">
        <a href="javascript:void(0)" @click="exportCSV">
          <span></span> <span></span> <span></span> <span></span> 导出CSV文件
        </a>
      </div>
    </main>
    <el-dialog
      title="修改信息框"
      :visible.sync="editDialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <div class="dialog-body">
        <span>电影名称：</span>
        <el-input placeholder="电影名称" v-model="editFilmName" clearable>
        </el-input>
        <span>电影信息：</span>
        <el-input placeholder="电影信息" v-model="editFilmDesc" clearable>
        </el-input>
        <span class="film-ratings">电影评分：</span>
        <el-slider
          v-model="editFilmScore"
          :format-tooltip="formatTooltip"
        ></el-slider>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button
          type="primary"
          style="padding: 12px 30px"
          @click="saveFilmInfo"
          >保 存</el-button
        >
      </span>
    </el-dialog>
    <el-dialog
      title="新增电影信息"
      :visible.sync="addDialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <div class="dialog-body">
        <span>电影名称：</span>
        <el-input placeholder="电影名称" v-model="addFilmName" clearable>
        </el-input>
        <span>电影信息：</span>
        <el-input placeholder="电影信息" v-model="addFilmDesc" clearable>
        </el-input>
        <span class="film-ratings">电影评分：</span>
        <el-slider
          v-model="addFilmScore"
          :format-tooltip="formatTooltip"
        ></el-slider>
      </div>

      <span slot="footer" class="dialog-footer">
        <el-button
          type="primary"
          style="padding: 12px 30px"
          @click="saveAddFilmInfo"
          >保 存</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'second-solution',
  data() {
    return {
      movieList: [],
      titles: ['编号', '电影名', '电影详情', '电影评分', '操作'],
      value: 60,
      editDialogVisible: false, // 编辑电影信息的提示框
      editFilmName: '',
      editFilmDesc: '',
      addDialogVisible: false, // 添加电影信息的提示框
      addFilmName: '',
      addFilmDesc: '',
      csvSeparator: ',', // CSV分隔符
      currentFilmNo: 0,
      editFilmScore: 3, // 修改后的电影分数初始值
      addFilmScore: 3, // 添加信息的电影分数初始值
      itemHeight: 80, //每一列的高度
      loadListNum: 12, //加载几条数据
      screenShowNum: 7, // div中显示的大小， 为了向下翻滚不会留白要稍大于loadListNum
      start: 0, //滚动过程显示的开始索引
      end: 14, //滚动过程显示的结束索引
    };
  },
  computed: {
    showList() {
      return this.movieList.slice(this.start, this.end);
    },
  },
  mounted() {
    //绝对定位对相对定位的偏移量
    this.$refs.list.style.top = this.start * this.itemHeight + 'px';
    //计算滚动容器高度
    this.$refs.listWrap.style.height =
      this.itemHeight * this.screenShowNum + 'px';
    var scrollDiv = document.getElementById('listWrap');
    scrollDiv.addEventListener('scroll', this.debounce(this.handleScroll, 0));
    this.movieList = this.$generateArray();
    this.initScrollHeight();
  },

  methods: {
    // 初始化总滚动条高度
    initScrollHeight() {
      //计算总的数据需要的高度，构造滚动条高度
      this.$refs.scrollBar.style.height =
        this.itemHeight * this.movieList.length + 'px';
    },
    // 清空新增信息框
    clearAddDialog() {
      this.addFilmName = '';
      this.addFilmDesc = '';
      this.addFilmScore = 0;
    },
    // 保存新增的信息
    saveAddFilmInfo() {
      this.addDialogVisible = false;

      let addFilm = {
        name: this.addFilmName,
        desc: this.addFilmDesc,
        score: this.formatTooltip(this.addFilmScore),
        status: false, // 如果不添加属性， 不会再observer里面观察回调
      };
      this.movieList.splice(this.currentFilmNo + 1, 0, addFilm);
      this.clearAddDialog();
      this.initScrollHeight();
    },
    // 手动添加影视信息
    addFilmInfo(index) {
      this.addDialogVisible = true;
      this.currentFilmNo = index + this.start;
    },
    // 删除相关影视信息
    onDelete(index) {
      this.movieList.splice(index + this.start, 1);
      this.initScrollHeight();
    },
    selectAll() {
      this.movieList.forEach(function (item, index, array) {
        item.status = !item.status;
      });
    },
    // 保存更改后的电影信息
    saveFilmInfo() {
      this.editDialogVisible = false;
      this.movieList[this.currentFilmNo].name = this.editFilmName;
      this.movieList[this.currentFilmNo].desc = this.editFilmDesc;
      this.movieList[this.currentFilmNo].score = this.formatTooltip(
        this.editFilmScore
      );
      this.$swal('Success', '信息保存成功', 'success');
    },
    // 通过slider的取值转换为1~5取值范围的分数
    formatTooltip(val) {
      return parseInt(val / 25) + 1;
    },
    // 数据中1~5的取值范围换算成slider显示分数
    convertToSlider(val) {
      return parseInt(val - 1) * 25;
    },
    // 弹出确认关闭的提示框
    handleClose(done) {
      this.$confirm('确认关闭？')
        .then((_) => {
          done();
        })
        .catch((_) => {
        });
    },
    // 导出CSV
    exportCSV() {
      // value = this.movieList,
      // columns = ["name", "desc", "score", "datetime"],
      // exportFilename = "电影信息表"
      const exportFilename = '电影信息表';
      const columns = ['name', 'desc', 'score|date'];
      const data = this.movieList.filter((item) => {
        return item.status === true;
      });
      let csv = '\ufeff';
      for (let i = 0; i < columns.length; i++) {
        const column = columns[i];
        // columns.header ???
        // columns[i] | column ???
        // 如何自动提取列名
        csv += '"' + columns[i] + '"';
        if (i < columns.length - 1) {
          csv += this.csvSeparator;
        }
      }
      data.forEach((item) => {
        this.$set(item, 'date', '2021-10-10');
      });
      // body
      data.forEach((record) => {
        csv += '\n';
        // tslint:disable-next-line: variable-name
        for (let i_1 = 0; i_1 < columns.length; i_1++) {
          const column = columns[i_1];
          csv += '"' + this.resolveFieldData(record, column) + '"';
          if (i_1 < columns.length - 1) {
            csv += this.csvSeparator;
          }
        }
      });
      const blob = new Blob([csv], {
        type: 'text/csv;charset=utf-8;',
      });
      if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveOrOpenBlob(blob, exportFilename + '.csv');
      } else {
        const link = document.createElement('a');
        link.style.display = 'none';
        document.body.appendChild(link);
        if (link.download !== undefined) {
          link.setAttribute('href', URL.createObjectURL(blob));
          link.setAttribute('download', exportFilename + '.csv');
          link.click();
        } else {
          csv = 'data:text/csv;charset=utf-8,' + csv;
          window.open(encodeURI(csv));
        }
        document.body.removeChild(link);
      }
    },
    // 处理表格中的数据
    resolveFieldData(data, field) {
      if (data && field) {
        // 检索的字符串没有出现返回-1
        if (field.indexOf('|') === -1) {
          return data[field];
        } else {
          const fields = field.split('|');
          const splitWord = ' | ';
          let value = '';
          for (let i = 0, len = fields.length; i < len; ++i) {
            if (value === null) {
              return null;
            }
            value += data[fields[i]] || '';
            if (i < len - 1) {
              value += splitWord;
            }
          }
          return value;
        }
      } else {
        return null;
      }
    },
    // 修改影视信息
    editFilmInfo(index) {
      this.editDialogVisible = true;
      this.currentFilmNo = index + this.start;
      this.editFilmName = this.movieList[index + this.start].name;
      this.editFilmDesc = this.movieList[index + this.start].desc;
      this.editFilmScore = this.convertToSlider(
        this.movieList[index + this.start].score
      );
    },
    // 获取点击的信息编号
    getClickNo(index) {
      this.movieList[index + this.start].status =
        !this.movieList[index + this.start].status;
    },
    // 使用函数防抖防止重复请求
    debounce(fn, wait) {
      var timer = null;
      return function () {
        if (timer !== null) {
          clearTimeout(timer);
        }
        timer = setTimeout(fn, wait);
      };
    },
    handleScroll() {
      //获取滚动高度
      let scrollTop = this.$refs.listWrap.scrollTop;
      //开始的数组索引
      this.start = Math.floor(scrollTop / this.itemHeight);
      //结束索引
      this.end = this.start + this.loadListNum;
      //绝对定位对相对定位的偏移量
      // this.$refs.list.style.top =
      //   this.start * this.itemHeight + (scrollTop % this.itemHeight) + "px";
      this.$refs.list.style.top = this.start * this.itemHeight + 'px';
    },
  },
};
</script>

<style lang="scss" scoped>
html {
  font-size: 20px;
}
.changeColorNo {
  span {
    color: #1abc9c;
  }
  border: 1px solid #1abc9c;
  background: #fff;
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.title-container {
  width: 90%;
  margin: 5vh auto;
}
.table {
  width: 90%;
  margin: 0vh auto;
  height: 50vh;
  border-radius: 8px;
  position: relative;
  // 防止scroll的条占用宽度
  overflow-y: overlay;
  box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.5);
}
.tbody {
  position: absolute;
  top: 0;
  width: 100%;
  left: 0;
}
.tbody span {
  height: 80px;
}
ul {
  list-style: none;
}
.title {
  span {
    font-weight: 900;
    font-size: 1.2rem;
  }
}
h1 {
  text-align: center;
  padding-bottom: 20px;
}
ul {
  li {
    list-style: none;
    display: flex;
    font-size: 1rem;
    line-height: 3.5rem;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    // 使用 > 选择器方式污染elementUi的样式
    > span {
      padding: 15px;
      text-align: center;
      animation: display 0.5s linear;
      animation-iteration-count: 1;
      color: #555;
      width: 20%;
      display: block;
      font-weight: 500;
      border-right: 1px solid #dcdfe6;
    }
  }
  li > span:nth-child(1) {
    width: 4%;
  }
  li > span:nth-child(2) {
    width: 8%;
  }
  li > span:nth-child(4) {
    width: 28%;
  }
  li > span:nth-child(6) {
    width: 30%;
  }
  li + li {
    border-top: none;
  }
  @keyframes display {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}
#label:hover {
  color: #25bb9b;
}
span >>> .button {
  padding: 12px 32px;
}
span >>> .el-rate {
  line-height: 3.5rem;
}
input[type='checkbox'] {
  margin-right: 8%;
  appearance: none;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  border: 2px solid #999;
  transition: 0.2s all linear;
  outline: none;
  position: relative;
  top: 3px;
}
input[type='checkbox']:checked {
  border: 5px solid #1abc9c;
  background: #fff;
}
div >>> .dialog-body {
  padding: 0px 20px;
  color: #606266;
  font-size: 14px;
  word-break: break-all;
}
.dialog-body span {
  padding-left: 5px;
  margin-top: 15px;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 2rem;
  display: block;
}
div >>> .el-slider {
  width: 67%;
  margin: 0 auto;
  margin-top: 15px;
  float: right;
}
div >>> .dialog-body::after {
  content: '';
  display: block; /*必须是块级元素*/
  clear: both;
}
.film-ratings {
  float: left;
}
.selected-all {
  cursor: pointer;
}
.selected-all:hover {
  color: #1abc9c;
  text-decoration: underline;
}
.box {
  width: 90%;
  margin: 0 auto;
}
.box a {
  position: relative;
  display: inline-block;
  padding: 13px 19px;
  color: #2e317c;
  font-size: 16px;
  text-decoration: none;
  text-transform: uppercase;
  overflow: hidden;
  transition: 0.5s;
  margin-top: 40px;
  letter-spacing: 4px;
}

.box a:hover {
  background: #8076a3;
  color: #fff;
  border-radius: 5px;
  box-shadow: 0 0 5px #8076a3, 0 0 25px #8076a3, 0 0 50px #8076a3,
    0 0 100px #8076a3;
}

.box a span {
  position: absolute;
  display: block;
}

.box a span:nth-child(1) {
  top: 0;
  left: -100%;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #8076a3);
  animation: btn-anim1 1s linear infinite;
}

@keyframes btn-anim1 {
  0% {
    left: -100%;
  }
  50%,
  100% {
    left: 100%;
  }
}

.box a span:nth-child(2) {
  top: -100%;
  right: 0;
  width: 2px;
  height: 100%;
  background: linear-gradient(180deg, transparent, #8076a3);
  animation: btn-anim2 1s linear infinite;
  animation-delay: 0.25s;
}

@keyframes btn-anim2 {
  0% {
    top: -100%;
  }
  50%,
  100% {
    top: 100%;
  }
}
.box a span:nth-child(3) {
  bottom: 0;
  right: -100%;
  width: 100%;
  height: 2px;
  background: linear-gradient(270deg, transparent, #8076a3);
  animation: btn-anim3 1s linear infinite;
  animation-delay: 0.5s;
}

@keyframes btn-anim3 {
  0% {
    right: -100%;
  }
  50%,
  100% {
    right: 100%;
  }
}

.box a span:nth-child(4) {
  bottom: -100%;
  left: 0;
  width: 2px;
  height: 100%;
  background: linear-gradient(360deg, transparent, #8076a3);
  animation: btn-anim4 1s linear infinite;
  animation-delay: 0.75s;
}

@keyframes btn-anim4 {
  0% {
    bottom: -100%;
  }
  50%,
  100% {
    bottom: 100%;
  }
}
</style>
